<?php
/**
 * Author: DefinitlyEvil
 * Created at: 2020/4/14 10:32
 */

namespace App\Tools;


class Encryption
{
    const CIPHER = 'AES-128-CBC';
    const SESSION_TIME = 60*60*24*7;
    //const SESSION_TIME = 10;

    public static function generate_token($user) {
        if(!isset($user) || $user === null || !isset($user['id']) || !isset($user['uuid'])) throw new \Exception("User can NOT be null! ");
        $expire = time() + self::SESSION_TIME;
        $json = json_encode([
            'id' => $user['id'],
            'username' => $user['username'],
            'uuid' => $user['uuid'],
            'donated' => intval($user['donated']) > 0 ? true : false,
            'expire' => $expire
        ]);
        return [self::encrypt_encoded($json), $expire];
    }

    public static function decrypt_token($token) {
        try {
            $dec = self::decrypt_encoded($token);
            if($dec === null) return null;
            $decoded = json_decode($dec, true);
            if(time() > $decoded['expire']) return null;
            return $decoded;
        } catch (\Exception $ex) {
            trigger_error('---------------');
            trigger_error($ex->getMessage());
            trigger_error($ex->getTraceAsString());
            trigger_error('---------------');
            return null;
        }
    }

    public static function iv() {
        $iv_len = openssl_cipher_iv_length(self::CIPHER);
        return openssl_random_pseudo_bytes($iv_len);
    }

    public static function encrypt_encoded($in) {
        $enc = self::encrypt($in);
        return sprintf('%s:%s', base64_encode($enc[0]), base64_encode($enc[1]));
    }

    public static function decrypt_encoded($in) {
        if(!is_string($in) or strpos($in, ':') === -1) return null;
        $s = explode(':', $in);
        if(count($s) !== 2) return null;
        $dec = self::decrypt(base64_decode($s[0]), base64_decode($s[1]));
        return $dec;
    }

    public static function encrypt($data) {
        $iv = self::iv();
        return [openssl_encrypt($data, self::CIPHER, hex2bin(getenv('SERVER_KEY')), OPENSSL_RAW_DATA, $iv), $iv];
    }

    public static function decrypt($data, $iv) {
        return openssl_decrypt($data, self::CIPHER, hex2bin(getenv('SERVER_KEY')), OPENSSL_RAW_DATA, $iv);
    }
}